// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: Phil Tjimos.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include "../src/pigasus-types.h"
#include <stdio.h>

class PigasusTypesTest : public TestFixture<PigasusTypesTest> {
 public:
  TEST_FIXTURE(PigasusTypesTest) {
    TEST_CASE(TestBasicListCreation); 
    TEST_CASE(TestListConcatenation);
    TEST_CASE(TestGetType); 
    TEST_CASE(TestListInBounds);
    TEST_CASE(TestListOutOfBounds);
    TEST_CASE(TestMapCreation);
    TEST_CASE(TestMapGetType);
    TEST_CASE(TestMapInBounds);
    TEST_CASE(TestMapOutOfBounds);
    TEST_CASE(TestFiles);  
  }

  void TestBasicListCreation() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;

    temp.Append(str_to_add);
    temp.Append(int_to_add);
    temp.Append(float_to_add);

    ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
  }
  
  void TestListConcatenation() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    
    List temp2;
    string str_to_add2 = "goodbye";
    int int_to_add2 = 2;
    double float_to_add2 = 2.0468;

    temp.Append(str_to_add);
    temp.Append(int_to_add);
    temp.Append(float_to_add);
    
    temp2.Append(str_to_add2);
    temp2.Append(int_to_add2);
    temp2.Append(float_to_add2);
    
    temp = temp + temp2;
    
    ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
    ASSERT_EQUALS(str_to_add2, *((string*)(temp[3])));
    ASSERT_EQUALS(int_to_add2, *((int*)(temp[4])));
    ASSERT_EQUALS(float_to_add2, *((double*)(temp[5])));
  }
  
  void TestGetType() {
    List temp;
    Map maptemp;
    int int_to_add;
    double float_to_add;
    File file;
    List temp2;
    
    temp.Append(temp);
    temp.Append(maptemp);
    temp.Append(int_to_add);
    temp.Append(float_to_add);
    temp.Append(file);
    temp.Append(temp2);
    
    ASSERT_EQUALS("list", temp.GetType(0));
    ASSERT_EQUALS("map", temp.GetType(1));
    ASSERT_EQUALS("int", temp.GetType(2));
    ASSERT_EQUALS("float", temp.GetType(3));
    ASSERT_EQUALS("file", temp.GetType(4));
    ASSERT_EQUALS("list", temp.GetType(5));
  }
  
  void TestListInBounds() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    
    for (int i=0; i<temp.GetSize(); i++) {
      if ( i==0 ) {
        ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
      } else if ( i==1 ) {
        ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
      } else {
        ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
      }
    }
  }
  
  void TestListOutOfBounds() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    void *element;
    
    for (int i=0; i< (temp.GetSize() + 1); i++) {
      element = temp[i];
    }
    
    ASSERT_EQUALS(NULL,element);
  }
  
  void TestMapCreation() {
    int a = 1;
    Map temp("test", a);
    
    ASSERT_EQUALS(a, *((int*)(temp["test"])));
      
    Map temp2;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    temp2 = Map("mystring",str_to_add) + Map("myint",int_to_add) + 
            Map("myfloat",float_to_add);
            
    ASSERT_EQUALS(str_to_add, *((string*)(temp2["mystring"])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp2["myint"])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp2["myfloat"]))); 
  }
  
  void TestMapGetType() {
    Map temp;
    List ltemp;
    int int_to_add;
    double float_to_add;
    File file;
    
    temp = Map("1" , temp) + Map("2", ltemp) + Map("3", int_to_add) 
          + Map("4",float_to_add) + Map("5",file);

    ASSERT_EQUALS("map", temp.GetType("1"));
    ASSERT_EQUALS("list", temp.GetType("2"));
    ASSERT_EQUALS("int", temp.GetType("3"));
    ASSERT_EQUALS("float", temp.GetType("4"));
    ASSERT_EQUALS("file", temp.GetType("5"));
  }
  
  void TestMapInBounds() {
    Map temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    temp = Map("mystring",str_to_add) + Map("myint",int_to_add) + 
           Map("myfloat",float_to_add);

    List keys = temp.GetKeys();
    string key;
    
    for (int i=0; i<keys.GetSize(); i++) {
      key = *((string*)(keys[i]));
      
      if ( i==0 ) {
        ASSERT_EQUALS(float_to_add, *((double*)(temp[key])));
      } else if ( i==1 ) {
        ASSERT_EQUALS(int_to_add, *((int*)(temp[key])));
      } else {
        ASSERT_EQUALS(str_to_add, *((string*)(temp[key])));
      }
    }
  }
  
  void TestMapOutOfBounds() {
    Map temp;
    void *val1;
    void *val2;
    string str;
    
    temp = Map("mystring","pigasus");
    
    val1 = temp["hello"];
    val2 = temp["notmystring"];
    str = *((string*)(temp["mystring"]));
    
    ASSERT_EQUALS(NULL,val1);
    ASSERT_EQUALS(NULL, val2);
    ASSERT_EQUALS("pigasus",str);
  }
   
  void TestFiles() {
    File temp("file1.txt");
    string temp2;
    temp2 = temp.Filename();
    
    ASSERT_EQUALS("file1.txt",temp2);
  }
    
};

REGISTER_FIXTURE(PigasusTypesTest);
